AC.OverlayPanel = Class.create();
Object.extend(AC.OverlayPanel.prototype, AC.ViewMaster.Viewer.prototype);
Object.extend(AC.OverlayPanel.prototype, Event.Listener);
Object.extend(AC.OverlayPanel.prototype, Event.Publisher);
Object.extend(AC.OverlayPanel.prototype, {
	
	closeBtn: null,
	overlay: null,
	overlayShadow: null,

	overlayId: '',
	overlayClasses: '',
	overlayContents: '',
	overlayShadowId: '',
	overlayShadowClasses: '',
	_overlayShadowSrc: null,
	_defaultOverlayShadowSrc: './global/elements/overlay/overlay_panel_default.png',
	defaultOverlayShadowSrc: function() {
        var baseTag = document.getElementsByTagName("base")[0],
			baseHref = baseTag ? baseTag.href : "",
			result = this._defaultOverlayShadowSrc;
			
			if(!baseHref || (baseHref && baseHref.lastIndexOf("/") !== (baseHref.length-1))) {
				result = "/"+result;
			}
			return baseHref+result;
	},
	
	order: 0,
	setOverlayShadowImageSrc: function(value) {
		this._overlayShadowSrc = (value) ? value : this.defaultOverlayShadowSrc();
		this.overlayshadowImage.src = this._overlayShadowSrc;
		if(this.isIE7()) {
		  this.overlayshadowImage.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this._overlayShadowSrc + "',sizingMethod='scale')";
			this.overlayshadowImage.src = "http://images.apple.com/global/elements/blank.gif";
		}
	},
	overlayShadowImageSrc: function() {
		return (this._overlayShadowSrc) ? this._overlayShadowSrc : this.defaultOverlayShadowSrc();
	},
	initialize: function(contents, view, triggerClassName, options) {
		
		this.overlayId = "OverlayPanel";
		this.overlayShadowId = "OverlayPanelShadow";
		this.createOverlay();
		//this.setDefaults();
		
		triggerClassName = triggerClassName || "OverlayPanel";
		AC.ViewMaster.Viewer.prototype.initialize.call(this,null,this.swapViewElement,triggerClassName,options);
		this.options.shouldAnimateContentChange = false;

		this.bindPositionOverlay = this.positionOverlay.bind(this);
	},
	
	createOverlay: function() {
		//this.closeBtn = Builder.node('a', {href:'#close', 'class':'close'}, 'Close');
		this.closeBtnContainer = document.createElement("div");
		this.closeBtnContainer.className = 'closeButtonContainer';
		this.closeBtn = document.createElement("a");
		this.closeBtn.href = '#close';
		this.closeBtn.className = 'close';
		this.closeBtn.appendChild(document.createTextNode("Close"));
		this.closeBtnContainer.appendChild(this.closeBtn);
		
		Event.observe(this.closeBtn, 'click', this.close.bindAsEventListener(this), false);	
		this.swapViewElement = Builder.node('div', {'class':'overlayPanelContent'});
		//this.buildContents();

		this.overlayshadowImage = Builder.node('img', {src:this.overlayShadowImageSrc(), alt:'', border:0, 'class':'overlayPanelShadowImage'});
		if(this.isIE7()) {
		  this.overlayshadowImage.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.overlayShadowImageSrc() + "',sizingMethod='scale')";
			this.overlayshadowImage.src = "http://images.apple.com/global/elements/blank.gif";
		}
		this.overlayshadow = Builder.node('div', {id:this.overlayShadowId, 'class':'overlaypanelshadow '+this.overlayShadowClasses}, [this.overlayshadowImage,this.swapViewElement]);
		this.overlay = $(Builder.node('div', {'id':this.overlayId, 'class':'overlaypanel '+this.overlayClasses, 'style':'left:-99999px; top:0;'}, [this.closeBtnContainer,this.overlayshadowImage,this.swapViewElement]));	
 		
		//document.body.appendChild(this.overlayshadow);
 		//document.body.appendChild(this.overlay);
	},
	
	//buildContents: function() {},
	isIE7: function() {
		return (AC.Detector.isIEStrict() && navigator.appVersion.indexOf("MSIE 6.0")>=0);
	},
	
 	setDefaults: function() {
		this.defaultWidth = this.overlay.offsetWidth;
		this.padleft = parseInt(Element.getStyle(this.overlay, 'marginLeft').replace(/px/i,''));
		this.padright = parseInt(Element.getStyle(this.overlay, 'marginRight').replace(/px/i,''));

		this.defaultHeight = this.overlay.offsetHeight;
		this.padtop = parseInt(Element.getStyle(this.overlay, 'marginTop').replace(/px/,''));
		this.padbottom = parseInt(Element.getStyle(this.overlay, 'marginBottom').replace(/px/,''));
 	},

 	setItemAttributes: function() {},

	
 	registerOverlay: function() {
		Event.observe(document, 'click', this.onClick.bindAsEventListener(this), false);
	},
	
	//From the swap view's stand point I'm going to treat the content as not loaded until the animation is over.
	isContentLoaded: function(swapView, content) {
		return false;
	},
	superContentDidLoad: AC.ViewMaster.Viewer.prototype.contentDidLoad,
	contentDidLoad: function(section, scriptFragment) {
        //Insert the overlay element. We need to do that before calling superContentDidLoad to make sure that dynamically loaded content creatinfg widgets can find their stuff
        document.body.appendChild(this.overlay);

    
		this.superContentDidLoad(section, scriptFragment);
		section.content.show();
		section.content.style.visibility = "hidden";
 		section.content.removeClassName("overlaydescription");
		
		//Add to the overlay as class name the section's id:
		this.overlay.addClassName(section.id);
		//this.overlayshadow.addClassName(section.id);
		
        
		//Capture this immediately
		this.setOriginFromEvent(this.currentSectionEvent)
		this.setDefaults();
        
		var self = this;
        //Gives some breathing room to the DOM/CSS to get it's acts together.
        this._isDisplaying = true;
		setTimeout(function(){self._display(section)},100);
	},
	_isDisplaying: false,
	_display: function(section) {
		this.setDefaults();
		this.setDimensions(this.currentSectionEvent, section.content);
		var self = this;
		return this.pop(this.defaultWidth, this.popPosition().top, this.defaultHeight, this.popPosition().left);
		
	},
	
	superWillShow: AC.ViewMaster.Viewer.prototype.willShow,
	willShow: function(view, outgoing, incoming) {
		return this.superWillShow(view, outgoing, incoming);
	},	
	
	superTriggerClicked: AC.ViewMaster.Viewer.prototype.triggerClicked,
	triggerClicked: function(evt,element) {
 		// stop the default event
 		if(evt) Event.stop(evt);

		this.superTriggerClicked(evt,element);
        if(this._isDisplaying) return;
        
		//Reset shadow image
		this.setOverlayShadowImageSrc(null);
		
		this._popPosition = null;
		this.currentSectionEvent = evt;
	
		
		
	},
	
	superShouldAnimateContentChange: AC.ViewMaster.Viewer.prototype.shouldAnimateContentChange,
	shouldAnimateContentChange: function(swapView, swapViewCurrentContent, swapViewNextContent) {
		if(AC.Detector.isiPhone()) return false;
		return this.superShouldAnimateContentChange(swapView, swapViewCurrentContent, swapViewNextContent);
	},
	
	willAnimate: function(view, outgoing, incoming, afterFinish) {
		//this.beforePop();
	},
	
	setOriginFromEvent: function(evt) {
		if(!evt) return;
		this.left = evt.pageX || evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		this.top = evt.pageY || evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
	},

	setDimensions: function(evt, item) {
 		// store the small size and position for later
 		this._width = (item.offsetWidth>80) ? 80 : item.offsetWidth;
		this.defaultWidth =  item.offsetWidth;
		var position = null;
		if(evt) position = Element.cumulativeOffset(evt.element());
		if(position) this.left = position.left;
		this.left = this.left || document.body.getDimensions().width / 2;
		this.defaultHeight = item.offsetHeight;
		this._height = Math.round((this._width*this.defaultHeight) / this.defaultWidth);
		if(position) this.top = position.top;
		this.top = this.top || document.body.getDimensions().height / 2;

		this.padleft = parseInt(Element.getStyle(item, 'marginLeft').replace(/px/i,''));
		this.padright = parseInt(Element.getStyle(item, 'marginRight').replace(/px/i,''));
		this.padtop = parseInt(Element.getStyle(item, 'marginTop').replace(/px/,''));
		this.padbottom = parseInt(Element.getStyle(item, 'marginBottom').replace(/px/,''));
	},
	
	windowSize: function() {
		var width = document.clientWidth || (document.documentElement.clientWidth || document.body.clientWidth);
		var height = document.clientHeight || (document.documentElement.clientHeight || document.body.clientHeight);
		var x = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
		var y = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
		
		if(AC.Detector.isiPhone()) {
			width = parseInt(980);
			height = parseInt(1212);
		}

		return {'width':width, 'height':height, 'x':x, 'y':y}
	},

 	popPosition: function(force) {
		if(!this._popPosition || force) {
			// set the position/offset of the image
			var left, top = null;
			var windowSize = this.windowSize();
			left = windowSize.x+(windowSize.width-this.defaultWidth-this.padleft-this.padright)/2;
			if (windowSize.width<this.defaultWidth+this.padleft+this.padright) left = windowSize.x-(this.padtop-this.closeBtnContainer.offsetWidth);

			top = (windowSize.y+(windowSize.height-this.defaultHeight-this.padtop-this.padbottom)/2);
			if (windowSize.height<this.defaultHeight+this.padtop+this.padbottom) {
				top = windowSize.y-(this.padtop-this.closeBtnContainer.offsetHeight);
			}
			if(top < 0 || top < 20) {
				top = 20;
			}
		
			this._popPosition = { left:left, top:top };
		}
		return this._popPosition;
 	},

	setWidth: function(value) {
		this.defaultWidth = value;
		this.overlay.style.width = value+"px";
	},
	width: function() {
		return this.defaultWidth;
	},
	setHeight: function(value) {
		this.defaultHeight = value;
		this.overlay.style.height = value+"px";
	},
	height: function() {
		return this.defaultHeight;
	},

 	prepPop: function() {},

 	beforePop: function() {
		Element.addClassName(this.overlay, 'isanim');
		Element.addClassName(this.overlayshadow, 'isanim');
		Element.addClassName(this.overlay, 'popped');
		Element.addClassName(this.overlayshadow, 'popped');
		if(AC.Detector.isIEStrict()) {
			//this.overlay.runtimeStyle.overflow = "hidden";
		}

		this.dispatchEvent('beforePop', this);
 	},

 	pop: function(width, top, height, left, afterFinish) {
		Element.setOpacity(this.overlay, 0);
		Element.setOpacity(this.overlayshadow, 0);

		//We set this._width at 80px;
		this._height = this._width*height/width;

		// prep the overlay/shadow for the effect
		this.overlay.style.width = this._width+'px';
		//this.overlayshadow.style.width = this._width+'px';

		this.overlay.style.height = this._height+'px';
		//this.overlayshadow.style.height = this._height+'px';

		this.overlay.style.left = this.left-this.padleft+'px';
		//this.overlayshadow.style.left = this.left+'px';

		this.overlay.style.top = this.top-this.padtop+'px';
		//this.overlayshadow.style.top = this.top+'px';
		
		this.overlay.style.display = '';

		var percent = (100*width) / this._width; 

		// do the craziness
		 new Effect.Parallel([
					new Effect.MoveBy(this.overlay, top-this.top+this.padtop, left-this.left+this.padleft, { sync:true }), 
					new Effect.Scale(this.overlay, percent, { sync:true, scaleContent:false, scaleMode:{ originalWidth: this._width, originalHeight: this._height }}),
					new Effect.Appear(this.overlay, { sync:true })
				],
				{ duration:0.3, beforeStart:this.beforePop.bind(this), afterFinish: this.afterPop.bind(this) }
			);
	},

	afterPop: function(item, i) {
		this.closeBtnContainer.style.display = "block";
		this.currentSection.content.style.visibility = "visible";
		this.setPoppedClass();

		Event.observe((document.onresize?document:window), 'resize', this.bindPositionOverlay);

		//dispatch afterPop event
		this.dispatchEvent('afterPop', this);
	},

	positionOverlay: function() {
		var pos = this.popPosition(true);
		this.overlay.setStyle({
			top: pos.top+'px',
			left: pos.left+'px'
		});
	},

	superWillClose: AC.ViewMaster.Viewer.prototype.willClose,
 	willClose: function() {
 		//this.setIsanimClass();
 		
 		//dispatch beforeClose event in case anything else needs to be closed
 		this.dispatchEvent('beforeClose', this);
		this.superWillClose(this, this.currentSection);
		
		// we need to close the section, otherwise it appears to misalign
		if (this.currentSection) this.currentSection.willClose();
 	},

	resetOverlay: function() {
		// reset the effect inline styles
		this.overlay.style.width = '';
		this.overlay.style.height = '';

		this.overlay.setOpacity('');
	},

	setPoppedClass: function() {
		Element.removeClassName(this.overlay, 'isanim');
		Element.removeClassName(this.overlayshadow, 'isanim');
		Element.addClassName(this.overlay, 'popped');
		Element.addClassName(this.overlayshadow, 'popped');	
	},
	
	setIsanimClass: function() {
		Element.addClassName(this.overlay, 'isanim');
		Element.addClassName(this.overlayshadow, 'isanim');
 		Element.removeClassName(this.overlay, 'popped');
 		Element.removeClassName(this.overlayshadow, 'popped');
	},
	
 	close: function(evt) {
 		if (evt) Event.stop(evt);

		var width = this.defaultWidth;
		var left = this.overlay.offsetLeft;
		var height = this.defaultHeight;
		var top = this.overlay.offsetTop;

		if (left>=0 && top>=0) { // if we are actually showing at the point of closure

            this.willClose(this);

            // Delay the actual effect that closes the overlay so there is 
            // some time for beforeClose notifications to be handled
            setTimeout(this._closeOpenOverlay.bind(this, width, left, height, top), 10);
		}
	},

    _closeOpenOverlay: function(width, left, height, top)
    {
        if (!AC.Detector.isiPhone()) {
            var percent = (100*this._width) / width; 

            // do the craziness
            new Effect.Parallel([
                new Effect.MoveBy(this.overlay, this.top-this.padtop-top, this.left-this.padleft-left, { sync:true }), 
                new Effect.Scale(this.overlay, percent, { sync:true, scaleContent:false, scaleMode:{ originalWidth: width, originalHeight: height }}),
                new Effect.Fade(this.overlay, { sync:true })
            ],
            { duration:0.3, afterFinish:this.afterClose.bind(this) });

            Event.stopObserving((document.onresize?document:window), 'resize', this.bindPositionOverlay);
        } else {
            this.afterClose();
        }
    },

 	afterClose: function() {
		//this.currentSection.content.style.visibility = "hidden";
		Element.removeClassName(this.overlay, 'isanim');
		Element.removeClassName(this.overlayshadow, 'isanim');
 		Element.removeClassName(this.overlay, 'popped');
 		Element.removeClassName(this.overlayshadow, 'popped');
		
		// causes problems for notifications:
		// setTimeout(function() {
		// 	this.view.setContent(null);
		// }.bind(this), 10);
		
		this.overlay.removeClassName(this.currentSection.id);
		//Reset OverlayShadowImageSrc in case it may have been altered by a delegate
		this.setOverlayShadowImageSrc(null);

		// reset everything
		this.overlay.style.width = '';
		this.overlayshadow.style.width = '';

		this.overlay.style.height = '';
		this.overlayshadow.style.height = '';

		this.overlay.style.left = '-99999px';
		this.overlayshadow.style.left = '';

		this.overlay.style.top = '0';
		this.overlayshadow.style.top = '';

		this.overlay.style.display = '';
		this.overlayshadow.style.display = '';
		
		// dispatch afterClose in case anything else needs to be reset
		this.dispatchEvent('afterClose', this);

		if (AC.Detector.isWebKit()) this.fixSafarisScrollBars();
		
		this.show(null, true);
        
        document.body.removeChild(this.overlay);
        this._isDisplaying = false;

 	},

	fixSafarisScrollBars: function() {
		var scrollTo = 1;
		var windowSize = this.windowSize();
		window.scroll(windowSize.x+scrollTo, windowSize.y+scrollTo);
		window.scroll(windowSize.x, windowSize.y);
 	}
});


Event.onDOMReady(function() {
	AC.OverlayPanel.overlay = new AC.OverlayPanel();
});

